package moa.learners.reservoir;

import java.util.Iterator;

import com.espertech.esper.collection.Pair;


/**
 * This abstract class represents the Reservoir itself,
 * some care was given as to make it generic but generalising
 * from one implementation does not ensure it was effectively
 * done.
 *
 * @param <E> type of the itemsets to be stored
 */
public abstract class AbstractSlides<E> {
	protected int cardSd;
	protected int winSize;

	/**
	 * @param cardSd	number of sequences to store
	 * @param winSize	sliding window size for each sequence
	 */
	public AbstractSlides( int cardSd, int winSize) {
		this.cardSd = cardSd;
		this.winSize = winSize;
	}

	/**
	 * @return	The Reservoir's capacity (maximum number of sequences to be stored)
	 */
	public int getMaxSequences() {
		return cardSd;
	}

	/**
	 * @return	The size of each sequence's sliding window
	 */
	public int getWindowSize() {
		return winSize;
	}

	/**
	 * Looks for the given sequence ID in the Reservoir
	 * 
	 * @param seqNumber	sequence ID
	 * @return true if the sequence is already stored in the Reservoir, false otherwise
	 */
	public abstract boolean hasSequenceNumber( String seqNumber);

	/**
	 * Adds a new itemset in the sequence's sliding window
	 * 
	 * @param seqNumber sequence ID
	 * @param itemSet	value(s) to be stored
	 * @return true if the sliding window was already full and had to be slid, false otherwise 
	 */
	public abstract boolean addAndSlide( String seqNumber, E itemSet);

	/**
	 * @return the number of sequences stored in the Reservoir
	 */
	public abstract int getNbSequences();

	/**
	 * Replaces a sequence already stored by a new sequence. The number of itemsets in the
	 * removed sequence determines how long it will be blacklisted.
	 * 
	 * @param loto			index of the sequence to replace
	 * @param seqNumber		sequence ID
	 * @param itemSet		first itemset of the new sequence
	 * @return				pair of values, first one is the ID of the removed sequence, second one the number of itemsets stored at the time of removal
	 */
	public abstract Pair<String, Integer> replace( int loto, String seqNumber, E itemSet);

	/**
	 * Add a new sequence to the Reservoir without replacing an older one, this method is
	 * supposedly used only at the beginning to fill the Reservoir
	 * 
	 * @param seqNumber sequence ID
	 * @param itemSet	value(s) to be stored
	 */
	public abstract void addSequence( String seqNumber, E itemSet);

	/**
	 * @return Iterator to the sequence IDs stored in the Reservoir
	 */
	public abstract Iterator<String> clientIterator();

	/**
	 * Returns an iterator to the contents of a sequence in the Reservoir
	 * 
	 * @param client	sequence ID
	 * @return	Iterator to the stored value(s)
	 */
	public abstract Iterator<E> itemIterator( String client);
}
